package cn.cookyfly.dailyreview.client;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;

public class Workbench extends VerticalPanel {
	
	public Workbench() {
		super();

		HorizontalPanel hTopPanel = new HorizontalPanel();
		hTopPanel.setSpacing(0);
		final HTML htmlPrevious = new HTML(Review.getPreviousItem());
		htmlPrevious.setWidth("150px");
		final HTML htmlNext = new HTML(Review.getNextItem());
		htmlNext.setWidth("150px");
		htmlNext.addStyleName("label-next");
		HorizontalPanel hTopmiddPanel = new HorizontalPanel();
		hTopmiddPanel.setSpacing(0);
		final Button btnPrevious = new Button("Previous");
		btnPrevious.setWidth("80px");
		final Button btnNext = new Button("Next");
		btnNext.setWidth("80px");
		final HTML htmlCurrent = new HTML(Review.getCurrentItem());
		htmlCurrent.setWidth("150px");
		htmlCurrent.addStyleName("label-current");
		
		HorizontalPanel hMiddPanel = new HorizontalPanel();
		hMiddPanel.setSpacing(3);
		final TextArea taReview = new TextArea();
		taReview.setSize("550px", "350px");
		final Button btnSave = new Button("Save");
		Button btnLogout = new Button("Save & Exit");
		
		setWidth("100%");
		setHorizontalAlignment(VerticalPanel.ALIGN_CENTER);
		setSpacing(20);
		
		hTopPanel.add(htmlPrevious);
		hTopmiddPanel.add(btnPrevious);
		hTopmiddPanel.add(htmlCurrent);
		hTopmiddPanel.add(btnNext);
		hTopPanel.add(hTopmiddPanel);
		hTopPanel.add(htmlNext);
		hMiddPanel.add(taReview);
		hMiddPanel.add(btnSave);
		add(hTopPanel);
		add(hMiddPanel);
		add(btnLogout);
		
		if (!Review.hasPrevious()) btnPrevious.setEnabled(false);
		if (!Review.hasNext()) btnNext.setEnabled(false);
		
		ClickHandler buttonHandler = new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				if (event.getSource() == btnPrevious) {
					showPrevious();
				} else if (event.getSource() == btnNext) {
					showNext();
				}
			}
			private void showPrevious() {
				if (!updateAndLoadReviewContent()) return;
				if (Review.hasPrevious()) {
					htmlNext.setText(Review.getCurrentItem());
					htmlCurrent.setText(Review.previousItem());
					htmlPrevious.setText(Review.getPreviousItem());
					taReview.setText(Review.getCurrentContent());
				}
				if (!Review.hasPrevious())
					btnPrevious.setEnabled(false);
				btnNext.setEnabled(true);
			}
			
			private void showNext() {
				if (!updateAndLoadReviewContent()) return;
				if (Review.hasNext()) {
					htmlPrevious.setText(Review.getCurrentItem());
					htmlCurrent.setText(Review.nextItem());
					htmlNext.setText(Review.getNextItem());
					taReview.setText(Review.getCurrentContent());
				}
				if (!Review.hasNext())
					btnNext.setEnabled(false);
				btnPrevious.setEnabled(true);
			}
			private boolean updateAndLoadReviewContent() {
				if (!Review.updateCurrentContent(taReview.getText())) {
					Window.alert("Saving reviewing in client failed! 'Review.current' out of bound?");
					return false;
				}
				return true;
			}
		};
		btnPrevious.addClickHandler(buttonHandler);
		btnNext.addClickHandler(buttonHandler);
		btnLogout.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				RpcCaller.getCaller().logout(new AsyncCallback<Boolean>() {
					public void onFailure(Throwable caught) {
						Window.alert("RPC calling failed.");
					}
					public void onSuccess(Boolean result) {
						DailyReview.showLogin();
					}
				});
			}
		});
		btnSave.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				btnSave.setText("SAVING...");
				RpcCaller.getCaller().saveReview(Review.getAllContent(), new AsyncCallback<Boolean>() {
					public void onFailure(Throwable caught) {
						btnSave.setText("Save");
						Window.alert("RPC calling failed while saving review.");
					}
					public void onSuccess(Boolean result) {
						btnSave.setText("Save");
						if (!result) {
							Window.alert("Saving review failed!");
						}
					}
					
				});
			}
		});
		
		Timer autoSave = new Timer() {
			public void run() {
				// TODO call RPC to save review content
			}
		};
		autoSave.scheduleRepeating(60 * 1000);// auto save review content to server every 1 minute
	}

}
